package common.project.epic.ui;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import common.project.epic.core.IIOEpicService;
import common.project.epic.core.ILocationEpicService;
import common.project.epic.core.LocationEpicService;
import common.project.epic.db.CurrentUser;
import common.project.epic.db.EpicDBAdapter;
import common.project.epic.ui.EpicNewMsg.LocServiceConnection;

import android.app.Activity;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class EpicMsgList extends ListActivity {
	private EpicDBAdapter dbHelper;
	private Cursor cursor;
	private SimpleCursorAdapter adapter;
	private String[] from;
	private int[] to;
	
	private String container;
	
	private String msg_id_to_remove;
	
//  IOEpicService mCommService;
//  LocationEpicService mLocationService;
	boolean mIOBound = false;
    boolean mLocBound = false;
	private ILocationEpicService mILocationEpicService = null;
	private IIOEpicService mIIOEpicService = null;
	private ServiceConnection mLocServiceConnection;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        Intent  callingIntent = getIntent();
        container = callingIntent.getStringExtra("container");
        
        setContentView(R.layout.epicmsglist);    
		this.getListView().setDividerHeight(2);	
		
		registerForContextMenu(getListView());
		
		from = new String[] {EpicDBAdapter.MSG_TITLE};
		to = new int[] {R.id.epicmsglist_item_title};
		
		// bind activity to location service 
        Intent intentloc = new Intent(this, LocationEpicService.class);
    	mLocServiceConnection = new LocServiceConnection();
        if(bindService(intentloc, mLocServiceConnection, Context.BIND_AUTO_CREATE)){}
        else {
        	Log.d("EPIC CREATE MSG", "NOT BINDED TO LOCATION SERVICE");
//        	Toast.makeText(getApplicationContext(), "Location not available", Toast.LENGTH_LONG).show();
        };
    }
   
    @Override
    public void onResume(){
    	super.onResume();
    	if(dbHelper!=null) {
        	dbHelper.open();
        }
        else {
        	dbHelper = new EpicDBAdapter(this);
        	dbHelper.open();
        }
    	Date t_now = new Date();
		long t_now_seconds = t_now.getTime()/1000;
        dbHelper.removeExpiredContents(t_now_seconds);   
        populateList();
    }
    
    @Override
    public void onPause(){
    	if (dbHelper != null) {
			dbHelper.close();
		}
    	super.onPause();
    }
    
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		Cursor c = dbHelper.getMsgId(id);
		String msg_id_to_query = c.getString(c.getColumnIndex(EpicDBAdapter.MSG_ID));
		final Intent intentEpicShowMsg = new Intent(EpicMsgList.this, EpicShowMsg.class);
    	intentEpicShowMsg.putExtra("msg_id_to_query", msg_id_to_query);
    	startActivity(intentEpicShowMsg);
	}

	private void populateList() {
		if(container!=null) {
			// TODO when activity is started from notification pending intent call EpicMsgListTab Activity
			// "cropUnread"
			if(container.equals("cropUnread")) {
				cursor = dbHelper.getContentsOrderedByReadUnread("crop"); // dbHelper.getUnreadContents("crop");
				container = "crop";
			}
			else if(container.equals("crop")) {
				cursor = dbHelper.getContents(container);
			}
			else if(container.equals("drop")) {
				cursor = dbHelper.getContents(container);
			}
			else if(container.equals("quarantine")) {
				cursor = dbHelper.getContents(container);
			}
		}
		else {
			cursor = dbHelper.getContents("crop");
		}
		startManagingCursor(cursor);
		
		// Now create an array adapter and set it to display using our row
		adapter = new EpicMsgListAdapter(this, this, R.layout.epicmsglist_item, cursor, from, to);
		
		setListAdapter(adapter);
	}
	
	@Override
    protected void onStop() {
    	// Unbind from the service
        if (mLocBound) {
            unbindService(mLocServiceConnection);
            mLocBound = false;
        }
        if (mIOBound) {
            unbindService(mIOServiceConnection);
            mIOBound = false;
        }
        super.onStop();
    }
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (dbHelper != null) {
			dbHelper.close();
		}
	}
	
	//########################################
    //##      SERVICE CONNECTIONS           ##
    //########################################
    class LocServiceConnection implements ServiceConnection {
    	public void onServiceConnected(ComponentName component, IBinder service) {
    		mILocationEpicService = ILocationEpicService.Stub.asInterface(service);
    	}
    	
    	public void onServiceDisconnected(ComponentName component) {
    		mLocBound = false;
    	}
    };
    
    ServiceConnection mIOServiceConnection = new ServiceConnection() {
    	public void onServiceConnected(ComponentName component, IBinder service) {
    		mIIOEpicService = IIOEpicService.Stub.asInterface(service);
    	}
    	public void onServiceDisconnected(ComponentName component) {
    		mIOBound = false;
    	}
    };
	
	//#################
    //## OPTION MENU ##
    //#################
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
//    	if(container.equals("cropUnread")) {
//			return false;
//		}
//		else {
			MenuInflater inflater = getMenuInflater();
		    inflater.inflate(R.menu.epicmsglist_menu, menu);
		    return true;
//		}
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	    case R.id.sort_by_proximity: {
	    	Location currentLoc = null;
	    	if(mILocationEpicService!=null) {
	    		try {
					currentLoc = (Location) mILocationEpicService.refreshLocation();
				} catch (Exception e) {
//					Toast.makeText(getApplicationContext(), "Location not available", Toast.LENGTH_LONG);
					e.printStackTrace();
				}
	    	}
	    	else {
				Criteria criteria = new Criteria();
				criteria.setAccuracy(Criteria.ACCURACY_COARSE);
				criteria.setPowerRequirement(Criteria.POWER_LOW);
				criteria.setAltitudeRequired(false);
				criteria.setBearingRequired(false);
				criteria.setSpeedRequired(false);
				criteria.setCostAllowed(true);		
				String context = Context.LOCATION_SERVICE;
				LocationManager locationManager = (LocationManager)getSystemService(context);
				String provider =  locationManager.getBestProvider(criteria, false);
				currentLoc = locationManager.getLastKnownLocation(provider);
	    	}
	    	double lat;
	    	double lon;
	    	if(currentLoc==null) {
	    		Toast.makeText(getApplicationContext(), "Location not available!\n" +
	    				"Sorting by proximity failed", Toast.LENGTH_LONG).show();
	    	}
	    	else {
	    		lat = currentLoc.getLatitude();
	    		lon = currentLoc.getLongitude();
	    		String[] ids = dbHelper.getMsgIdOrderedByProximity(lat, lon, container);
	    		cursor = dbHelper.getContents(ids);
				startManagingCursor(cursor);
				adapter = new EpicMsgListAdapter(this, this, R.layout.epicmsglist_item, cursor, from, to);
				setListAdapter(adapter);
	    	}
	        return true;
	    }
	    case R.id.sort_by_expire_time: {
	    	cursor = dbHelper.getContentsOrderedByExpirationTime(container);
			startManagingCursor(cursor);
			adapter = new EpicMsgListAdapter(this, this, R.layout.epicmsglist_item, cursor, from, to);
			setListAdapter(adapter);
	        return true;
	    }
	    case R.id.sort_by_matching_categories: {
	    	cursor = dbHelper.getContentsOrderedByMatchingCategories(container);
			startManagingCursor(cursor);
			adapter = new EpicMsgListAdapter(this, this, R.layout.epicmsglist_item, cursor, from, to);
			setListAdapter(adapter);
	        return true;
	    }
	    case R.id.sort_read_unread: {
	    	cursor = dbHelper.getContentsOrderedByReadUnread(container);
			startManagingCursor(cursor);
			adapter = new EpicMsgListAdapter(this, this, R.layout.epicmsglist_item, cursor, from, to);
			setListAdapter(adapter);
	    	return true;
	    }
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
	
	
	//##################
    //## CONTEXT MENU ##
    //##################
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
	  super.onCreateContextMenu(menu, v, menuInfo);
	  
	  AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
	  Cursor cursor_tmp = dbHelper.getMsgId(info.id);
	  msg_id_to_remove = cursor_tmp.getString(cursor_tmp.getColumnIndex(EpicDBAdapter.MSG_ID));
	  cursor_tmp = dbHelper.getContent(msg_id_to_remove);
	  String title = cursor_tmp.getString(cursor_tmp.getColumnIndex(EpicDBAdapter.MSG_TITLE));
	  if(title != null) {
		  if(title.length()>10) {
			  menu.setHeaderTitle(title.substring(0, 10) + "...");
		  }
		  else {
			  menu.setHeaderTitle(title);
		  }
	  }
	  else {
		  menu.setHeaderTitle("Message without text");
	  }
	  
	  setContextMenuMsgId((String) v.getContentDescription());
	  MenuInflater inflater = getMenuInflater();
	  inflater.inflate(R.menu.remove_element_menu, menu);
	}
	
	private String context_menu_msg_id; 
	private void setContextMenuMsgId(String msg_id) {
		context_menu_msg_id = msg_id;
	}
	private String getContextMenuMsgId() {
		return context_menu_msg_id;
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		switch (item.getItemId()) {
	    case R.id.delete_msg: {
	    	if(dbHelper!=null) {
	        	dbHelper.open();
	        }
	        else {
	        	dbHelper = new EpicDBAdapter(this);
	        	dbHelper.open();
	        }
	    	boolean deletionSucceeded = dbHelper.markAsDeleted(msg_id_to_remove);
	    	if(deletionSucceeded) {
	    		Log.d("Epic", "Epic message marked as deleted.");
	    		populateList();
	    	}
	    	else {
	    		Log.d("Epic", "Error in deleting this Epic message!");
	    	}
	        return deletionSucceeded;
	    }
	    case R.id.tag_msg: {
	    	Toast.makeText(getApplicationContext(), "Mark messages not yet available", 2000).show();
	        return true;
	    }
	  default:
	    return super.onContextItemSelected(item);
	  }
	}
	
	
}